import json
import uuid
import struct

from PyQt6.QtCore import QDir

import Global

from PyQt6.QtNetwork import QTcpServer, QTcpSocket, QHostAddress


class NetWork(QTcpServer):
    def __init__(self,port):
        super(NetWork,self).__init__()
        self.port=port

    def startServer(self):
        try:
            if self.listen(QHostAddress.SpecialAddress.LocalHost, self.port):
                Global.LOGD(f"监听端口成功:{self.port}")
                return True
            else:
                Global.LOGE(f"监听端口失败:{self.port},错误:{self.errorString()}")
                return False
        except Exception as e:
            Global.LOGE(f"启动服务器时发生错误: {e}")
            return False

    def stopServer(self):
        try:
            self.close()
        except Exception as e:
            Global.LOGE(f"停止服务器时发生错误: {e}")

    def incomingConnection(self, socketDescriptor):
        try:
            clientSocket = QTcpSocket(self)  # 将clientSocket的父对象设置为self，确保生命周期管理
            if clientSocket.setSocketDescriptor(socketDescriptor):
                clientSocket.readyRead.connect(self.OnRecive)
                clientSocket.disconnected.connect(self.OnClose)
        except Exception as e:
            Global.LOGE(f"处理新连接时发生错误: {e}")

    def OnRecive(self):
        try:
            socket = self.sender()
            handle = socket.socketDescriptor()
            if socket.bytesAvailable() < 4:
                return
            while True:
                # 判断缓冲区数据长度,是一个完整的包则处理
                header = socket.peek(4)
                dataLen = int.from_bytes(header, "little", signed=False)
                if dataLen <= 0 or socket.bytesAvailable() < dataLen:
                    break
                socket.read(4)
                data: bytes = socket.read(dataLen-4)
                jsonstr = data.decode()
                try:
                    msg = json.loads(jsonstr)
                    self.Handle_Msg(msg,socket)
                except json.JSONDecodeError as e:
                    Global.LOGE(f"JSON解析错误: {e}")
                    break
        except Exception as e:
            Global.LOGE(f"接收数据时发生错误: {e}")

    def OnClose(self):
        try:
            socket = self.sender()
            socket.close()
            for game in Global.G_Game:
                if game.socket == socket :
                    game.data["processID"]=0
                    game.socket=None
                    game.data["status"]="脱机"
                    game.data["notes"] = ""
        except Exception as e:
            Global.LOGE(f"处理断开连接时发生错误: {e}")

    def SendData(self,sort,data):
        try:
            if sort == -1 :
                return False
            if Global.G_Game[sort].socket==None or Global.G_Game[sort].socket.connected==False:
                return False
            if isinstance(data, dict):
                data = json.dumps(data,ensure_ascii=False,indent=None)
            #Global.LOGD(sort,"中控Send->"+data)
            head=len(data.encode())+4
            senddata=head.to_bytes(4, 'little', signed=False)+data.encode()
            return Global.G_Game[sort].socket.write(senddata)
        except Exception as e:
            Global.LOGE(f"发送数据时发生错误: {e}")
            return False

    def Handle_Msg(self,msg,socket):
        try:
            #Global.LOGD(f"recv->{msg}")
            cmd = msg.get("method", '')
            pid = msg.get("pid", 0)
            user = msg.get("user", '')
            serverId = msg.get("serverId", '')
            isRunScript=msg.get("isRunScript", False)
            sort = self.GetIndex(pid,user,serverId)
            if sort == -1 :
                Global.LOGE(f"未找到索引{pid}")
                return
            if Global.G_Game[sort].socket !=socket :
                # if Global.G_Game[sort].data["processID"] == 0:
                #     Global.G_Game[sort].data["processID"] = pid
                Global.G_Game[sort].socket = socket
            if isRunScript :
                Global.G_Game[sort].data["status"]="运行"
            else:
                Global.G_Game[sort].data["status"]="联机"
            if cmd=="Hello" :
                print("hello")
            elif cmd=="GetConfig":
                self.SendConfig(sort)
            elif cmd=="GetPlayerInfo":
                Global.G_Game[sort].data["level"]=msg.get("level", 0)
                Global.G_Game[sort].data["jobId"] = msg.get("jobId", 0)
                Global.G_Game[sort].data["roleName"] = msg.get("roleName", '')
                Global.G_Game[sort].data["mapName"] = msg.get("mapName", '')
                Global.G_Game[sort].data["money"] = msg.get("money", 0)#金币
                Global.G_Game[sort].data["gold"] = msg.get("gold", 0)#琥珀
            elif cmd == "GetAccountInfo":
                data={}
                data["method"]=cmd
                data["user"]=Global.G_Game[sort].data["user"]
                data["pass"] = Global.G_Game[sort].data["pass"]
                data["areaId"] = int(Global.G_Game[sort].data["areaId"])
                data["areaName"] = Global.G_Game[sort].data["areaName"]
                data["serverId"] = int(Global.G_Game[sort].data["serverId"])
                data["serverName"] = Global.G_Game[sort].data["serverName"]
                self.SendData(sort,data)
            elif cmd=="PrintLog":
                msgData = msg.get("data", '')
                if len(msgData)>0:
                    Global.LOGD(sort, msgData)
                    Global.G_Game[sort].data["notes"] =msgData
            elif cmd == "GetPosition":
                mapid = msg.get("mapid", 0)
                x = msg.get("x", 0)
                y = msg.get("y", 0)
                z = msg.get("z", 0)
                # 修改为保留小数点后两位
                Global.mainWindow.configDlg.lineEdit_CurPosition.setText(f"{x:.2f},{y:.2f},{z:.2f}")
        except Exception as e:
            Global.LOGE(f"处理消息时发生错误: {e},消息:{msg}")

    def GetIndex(self,pid,user,serverid):
        for i in range(len(Global.G_Game)):
            if Global.G_Game[i].data["processID"]==pid or (Global.G_Game[i].data["user"]==user and Global.G_Game[i].data["serverId"]==serverid):
                return i
        return -1

    def SendConfig(self, sort):
        try:
            if sort == -1:
                return
            data = {}
            data["method"] = "GetConfig"
            data["path"] = QDir.current().absolutePath() + "/Script"

            with open("config/" + Global.G_Game[sort].data["config"], 'r', encoding='utf-8') as configfile:
                FileData = configfile.read()

            data["config"] = json.loads(FileData)

            # 判断 config 字段中的 采集配置 字段是否存在
            if "采集配置" in data["config"]:
                collect_config = data["config"]["采集配置"]
                # 判断 Points 字段是否存在
                if "Points" in collect_config:
                    points = collect_config["Points"]
                    collect_config["Points"]=[]
                    posDatas = points.split('|')
                    for pos in posDatas:
                        if not self.ValidPos(pos):
                            continue
                        x, y, z = pos.split(',')
                        collect_config["Points"].append({'x': float(x), 'y': float(y), 'z': float(z)})

            self.SendData(sort, json.dumps(data,ensure_ascii=False, indent=None))
        except Exception as e:
            Global.LOGE(f"发送配置时发生错误: {e}")

    def ValidPos(self,position):
        import re
        pattern = r'^-?\d+\.\d+,-?\d+\.\d+,-?\d+\.\d+$'
        if not re.match(pattern, position):
            return False
        return True